<template>
  <div>
    <el-form label-width="80px" :inline="false" size="default">
      <el-form-item label="SPU名称">
        <el-input v-model="spuInfo.spuName"></el-input>
      </el-form-item>
      <el-form-item label="品牌">
        <el-select placeholder="请选择品牌" clearable v-model="spuInfo.tmId">
          <el-option v-for="item in TrademarkListAll" :key="item.id" :label="item.tmName" :value="item.id"/>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input
            v-model="spuInfo.description"
            size="default"
            clearable
            type="textarea"
        ></el-input>
      </el-form-item>
      <el-form-item label="SPU图片">
        <el-upload
            v-model:file-list="SpuImageList"
            action="http://gmall-h5-api.atguigu.cn/admin/product/upload"
            list-type="picture-card"
            :on-preview="handlePictureCardPreview"
            :on-remove="handleRemove"
        >
          <el-icon>
            <ele-Plus/>
          </el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img :src="dialogImageUrl" alt="Preview Image"/>
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性">
        <el-select placeholder="请选择销售属性" v-model="saleAttrItem">
          <el-option
              :value="`${item.id}:${item.name}`"
              v-for="item in unSaleAttrListAll"
              :key="item.id"
              :label="item.name"
          />
        </el-select>

        <el-button @click="addSaleAttrItem" icon="ele-Plus" type="primary" style="margin-left: 20px"
        >添加销售属性
        </el-button
        >
      </el-form-item>
      <el-form-item>
        <el-table border stripe :data="SaleAttrSelfList">
          <el-table-column type="index" width="80" label="序号"/>
          <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
          <el-table-column label="属性值名称列表">
            <template #default="{row}">
              <el-tag
                  v-for="(item,index) in row.spuSaleAttrValueList"
                  :key="item.id"
                  closable
                  @close="removeSaleAttrValueItem(row,index)"
              >
                {{ item.saleAttrValueName }}
              </el-tag>
              <el-button v-if="!row.isEdit" size="small" icon="ele-Plus" @click="toInput(row)">添加属性值</el-button>
              <el-input
                  v-model="saleAttrValueItem"
                  ref="inputEle"
                  v-else
                  @blur="toButton(row)" placeholder="请新增属性值"
                  size="small"
                  clearable
              >
              </el-input>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template #default="{row,$index}">
              <el-button @click="removeSaleAttrItem($index)" type="danger" size="small" icon="ele-Delete"></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submit">保存</el-button>
        <el-button @click="emit('changeType', 0)">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script lang="ts">
import {defineComponent, ref} from "vue";

export default defineComponent({
  name: "SpuForm",
});
</script>

<script setup lang="ts">
import type {
  baseSaleAttrListType, SpuInfoType,
  SpuItemType, spuSaleAttrItemType,
  spuSaleAttrListType,
  spuSaleImgListType
} from "@/api/spu";
import {computed, nextTick, onMounted, ref} from "vue";
import type {UploadProps} from "element-plus/es";
import {ElMessage} from "element-plus/es";
import {type TrademarkListAllType, reqGetTrademarkListAllAsync} from "@/api/trademark";
import {
  reqAddSpuAsync,
  reqBaseSaleAttrList,
  reqSaleAttrSelf,
  reqSpuImageList,
  reqUpdateSpuAsync
} from "@/api/spu";

// 得到修改或者添加的数据
const props = defineProps<{
  spuInfo: SpuInfoType
}>()
//接收切换type的自定义事件
const emit = defineEmits<{
  (event: "changeType", type: number, row?: SpuItemType): void;
}>();

// 上传的图片地址
const dialogImageUrl = ref("");
// 缩略图的显示隐藏
const dialogVisible = ref(false);

// 删除的回调
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles);
};

// 显示缩略图的回调
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

// 保存所有的品牌列表数据
const TrademarkListAll = ref<TrademarkListAllType>([])
// 保存所有销售属性列表
const SaleAttrListAll = ref<baseSaleAttrListType>([])
// 保存当前spuId下的所有图片列表
const SpuImageList = ref<spuSaleImgListType>([])
// 保存当前spuId获取自己的销售属性属性值列表
const SaleAttrSelfList = ref<spuSaleAttrListType>([])

// 判断点击修改或者添加进来的spuForm
onMounted(async () => {
  try {
    if (props.spuInfo.id) { // 代表是通过修改进入的
      //  发送 4 请求  所有品牌列表、所有销售属性列表、根据spuId获取图片列表、根据spuId获取销售属性列表
      const p1 = reqGetTrademarkListAllAsync()  //  所有品牌列表
      const p2 = reqBaseSaleAttrList()  // 所有销售属性列表
      const p3 = reqSpuImageList(props.spuInfo.id)  // 根据spuId获取图片列表
      const p4 = reqSaleAttrSelf(props.spuInfo.id)  // 根据spuId获取自己的销售属性列表

      // 四个请求一起发 四个都成功则成功 返回一个 Promise value是一个数组
      const result = await Promise.all([p1, p2, p3, p4])
      TrademarkListAll.value = result[0]
      SaleAttrListAll.value = result[1]
      SpuImageList.value = result[2]
      SaleAttrSelfList.value = result[3]

      // 照片墙渲染需要name和url属性 所以需要格外添加这两个属性  后续添加spu需剔除
      SpuImageList.value.forEach(item => {
        item.name = item.imgName
        item.url = item.imgUrl
      })

      // 添加属性值按钮和输入添加属性值输入框相互切换   添加额外属性 isEdit 控制  后续会剔除
      SaleAttrSelfList.value.forEach(item => {
        item.isEdit = false
      })
    } else {  // 通过添加进入的
      //  发送 2 请求  所有品牌列表、所有销售属性列表
      const p1 = reqGetTrademarkListAllAsync()  //  所有品牌列表
      const p2 = reqBaseSaleAttrList()  // 所有销售属性列表

      // 两个请求一起发 四个都成功则成功 返回一个 Promise value是一个数组
      const result = await Promise.all([p1, p2])
      TrademarkListAll.value = result[0]
      SaleAttrListAll.value = result[1]
    }
  } catch (e: any) {
    ElMessage.error(e.massage)
  }
})

// 过滤需要显示的销售属性  --- 拿已有的销售属性和全部的销售属性对比
// 如果是添加的话 已有的销售属性无 所以 过滤会自动返回 全部的销售属性 不需要单独去判断
const unSaleAttrListAll = computed(() => {
  return SaleAttrListAll.value.filter(item => {
    return !SaleAttrSelfList.value.some(selfItem => {
      return selfItem.saleAttrName === item.name
    })
  })
})

// 收集需要添加的销售属性
const saleAttrItem = ref('')

// 点击添加销售属性时  添加到自己的销售属性列表中
const addSaleAttrItem = () => {
  // 添加的销售属性 拆分
  const [id, name] = saleAttrItem.value.split(':')

  // 添加到自己的销售属性列表中
  SaleAttrSelfList.value.push({
    baseSaleAttrId: +id, //当前销售属性在基础销售属性列表中的id
    saleAttrName: name, //当前销售属性的名称
    spuId: props.spuInfo.id,  //当前销售属性所在的spuId
    spuSaleAttrValueList: [],  //当前整体的Spu销售的属性值列表数据的限制
    isEdit: false  // 添加属性值按钮和输入添加属性值输入框相互切换   添加额外属性 isEdit 控制  后续会剔除
  })

  // 清空选择销售属性框的值
  saleAttrItem.value = ''
}

// 获取输入属性值的input的DOM节点
const inputEle = ref<HTMLInputElement>()

// 添加添加属性值按钮 切换成 输入模式
const toInput = (row: spuSaleAttrItemType) => {
  //  切换成 输入模式
  row.isEdit = true

  // 自动获取焦点
  nextTick(() => {
    inputEle.value?.focus()
  })
}

// 收集input 输入框 输入的销售属性值
const saleAttrValueItem = ref('')

// 输入模式的input 失焦的时候切换成 查看模式
const toButton = (row: spuSaleAttrItemType) => {
  // 切换成 查看模式
  row.isEdit = false

  if (!saleAttrValueItem.value) return ElMessage.error("输入的销售属性值不能为空")

  // 查看添加的销售属性值 是否 重复
  const isRepeat = row.spuSaleAttrValueList.some(item => {
    return item.saleAttrValueName === saleAttrValueItem.value
  })

  // 如果重复
  if (isRepeat) {
    // 清空 输入框 输入的销售属性值
    saleAttrValueItem.value = ''

    return ElMessage.error('您输入的值重复了')
  }

  // 并将需要添加的销售属性值保存在销售属性值列表中
  row.spuSaleAttrValueList.push({
    baseSaleAttrId: row.baseSaleAttrId,  //当前销售属性值所在的销售属性的id  添加的时候后台不需要这个值
    isChecked: '',  //当前销售属性值是否是被选中状态  添加的时候后台不需要这个值
    saleAttrName: row.saleAttrName, //所在的销售属性的名称
    saleAttrValueName: saleAttrValueItem.value, //所在的销售属性值的名称
    spuId: props.spuInfo.id //当前销售属性所在的spu的id  添加的时候后台不需要这个值
  })

  // 清空 输入框 输入的销售属性值
  saleAttrValueItem.value = ''
}

// 删除添加的销售属性值
const removeSaleAttrValueItem = (row: spuSaleAttrItemType, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1)
}
// 删除添加的销售属性
const removeSaleAttrItem = (index: number) => {
  SaleAttrSelfList.value.splice(index, 1)
}

// 提交功能
const submit = async () => {
  // 处理销售属性列表不需要的数据 isEdit
  SaleAttrSelfList.value.forEach(item => {
    delete item.isEdit
  })
  // 处理图片列表中不需要的数据和重写需要的数据的属性名  后台添加/修改图片列表只需要 imgName和imgUrl
  SpuImageList.value = SpuImageList.value.map(item => {
    if (item.response) {  // 代表新添加的照片
      return {
        spuId: props.spuInfo.id,   // 添加在那个 spu值 的下面的 spuId
        imgName: item.name as string,  // 图片名
        imgUrl: item.response.data,   // 图片地址
      }
    } else {
      delete item.name; // 添加和修改的照片墙需要  后续剔除
      delete item.url;    // 添加和修改的照片墙需要   后续剔除
      delete item.response;
      return item
    }
  })

  // 综合需要添加或者修改的数据
  props.spuInfo.spuSaleAttrList = SaleAttrSelfList.value;
  props.spuInfo.spuImageList = SpuImageList.value;

  console.log(props.spuInfo)
  // 发送请求
  try {
    if (props.spuInfo.id) {  // 代表是修改操作
      await reqUpdateSpuAsync(props.spuInfo)
      ElMessage.success('修改成功')
    } else { // 代表是添加操作
      await reqAddSpuAsync(props.spuInfo)
      ElMessage.success('添加成功')
    }
    // 回到spuList页
    emit('changeType', 0)
  } catch (e: any) {
    // 回到spuList页
    emit('changeType', 0)
    ElMessage.error(e.message)
  }
}
</script>

<style scoped></style>
